package com.dong.pointviewpager.widget

import android.content.Context
import android.util.AttributeSet
import android.util.SparseArray
import android.view.View
import android.widget.ImageView
import androidx.viewpager.widget.ViewPager
import com.dong.pointviewpager.adapter.LoopPagerAdapter
import com.dong.pointviewpager.config.LoopViewPagerConfig
import com.dong.pointviewpager.interfaces.IPagerBean
import com.dong.pointviewpager.interfaces.listener.OnLoopPageChangedListener
import com.dong.pointviewpager.interfaces.listener.OnLoopPagerClickListener
import com.dong.pointviewpager.interfaces.listener.OnPagerStateChangedListener
import com.dong.pointviewpager.manager.ScrollerManger
import com.dong.pointviewpager.utils.DensityUtils.dp2px
import java.util.*
import kotlin.math.abs

/**
 * Created by Dong on 2018/3/15.
 */
open class LoopViewPager<T : IPagerBean> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : ViewPager(context, attrs) {

    var beans = mutableListOf<T>()
        set(value) {
            beans.clear()
            beans.addAll(value)
            offscreenPageLimit = if(isPageCache) beans.size + LoopViewPagerConfig.NUM_POSITION_CASE * 2 else 0
        }
    var isPageCache = false

    var onLoopPageChangeListener: OnLoopPageChangedListener? = null
    var onLoopPagerClickListener: OnLoopPagerClickListener<T>? = null
    var onPagerStateChangedListener: OnPagerStateChangedListener? = null

    private val config = LoopViewPagerConfig()
    private val scrollManager = ScrollerManger.Builder().build()
    private var loopPagerAdapter: LoopPagerAdapter<T>? = null
    private val childCenterXAbs = ArrayList<Int>()
    private val childIndex = SparseArray<Int>()
    private var preDataPosition = -1 //位置标记，防止回调两次

    init {
        addOnPageChangeListener(object : OnPageChangeListener {
            override fun onPageScrolled(pos: Int, offset: Float, positionOffsetPixels: Int) {
                if (beans.size == 0) return
                var position = loopPagerAdapter!!.getDataPosition(pos)
                var positionOffset = offset
                if (position == beans.size - 1) {
                    if (positionOffset > 0.5) position = 0
                    positionOffset = 0f
                }
                //主要是告知PointView自己滑动的位置，更新小圆点位置
                onPagerStateChangedListener?.onPagerScroll(position, positionOffset, positionOffsetPixels)
                onLoopPageChangeListener?.onLoopPageScrolled(position, offset, positionOffsetPixels)
            }

            override fun onPageSelected(position: Int) {
                scrollManager.sendScrollMessage(this@LoopViewPager)
                loopPagerAdapter?.run {
                    if(preDataPosition != getDataPosition(position)) {
                        onLoopPageChangeListener?.onLoopPageSelected(getDataPosition(position))
                    }
                    preDataPosition = getDataPosition(position)
                }
            }

            override fun onPageScrollStateChanged(state: Int) {
                //循环播放时，滑动到最后或第一页，重新定位
                scrollManager.scrollState = state
                if (config.isLoop && state == SCROLL_STATE_IDLE) {
                    loopPagerAdapter?.run {
                        setRealCurrentItem(this@LoopViewPager, currentItem)
                    }
                }
                onLoopPageChangeListener?.onLoopPageScrollStateChanged(state)
            }
        })
    }

    fun initialise() {
        loopPagerAdapter = LoopPagerAdapter(context, beans, config).apply {
            onLoopPagerClickListener = this@LoopViewPager.onLoopPagerClickListener
        }
        adapter = loopPagerAdapter
        onPagerStateChangedListener?.onPagerDataChanged(beans.size)

        setStartPosition()
        autoPlay()
    }

    fun notifyDataChanged(){
        loopPagerAdapter?.notifyDataSetChanged()
        onPagerStateChangedListener?.onPagerDataChanged(beans.size)
    }

    fun setAuto(isAuto: Boolean){
        scrollManager.isAuto = isAuto
    }

    fun setAutoTime(autoTime: Int){
        scrollManager.autoTime = autoTime
    }

    fun setLoop(isLooper: Boolean){
        config.isLoop = isLooper
    }

    fun setRadius(radius: Float){
        config.radius = dp2px(context, radius)
    }

    fun setImageScale(scaleType: ImageView.ScaleType){
        config.imageScale = scaleType
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        scrollManager.release()
    }

    override fun getChildDrawingOrder(childCount: Int, n: Int): Int {
        if (n == 0 || childIndex.size() != childCount) {
            childCenterXAbs.clear()
            childIndex.clear()
            val viewCenterX = getViewCenterX(this)
            for (i in 0 until childCount) {
                var indexAbs = abs(viewCenterX - getViewCenterX(getChildAt(i)))
                //两个距离相同，后来的那个做自增，从而保持abs不同
                if (childIndex[indexAbs] != null) {
                    ++indexAbs
                }
                childCenterXAbs.add(indexAbs)
                childIndex.append(indexAbs, i)
            }
            childCenterXAbs.sort() //1,0,2  0,1,2
        }
        //那个item距离中心点远一些，就先draw它。（最近的就是中间放大的item,最后draw）(Gallery谁压着谁)
        return childIndex[childCenterXAbs[childCount - 1 - n]]
    }

    private fun getViewCenterX(view: View): Int {
        val array = IntArray(2)
        view.getLocationOnScreen(array)
        return array[0] + view.width / 2
    }

    private fun setStartPosition() {
        loopPagerAdapter?.run {
            if(getStartPosition() < count){
                setCurrentItem(getStartPosition(), false)
            }
        }
    }

    private fun autoPlay() {
        scrollManager.sendScrollMessage(this)
    }

}